/**
 * 前言： setTimeout是延迟执行函数，而setInterval就像一个定时器，每间隔一定时间就触发一次回调
 * 为什么要用setTimeout去实现setInterval
 */
function mySetInterval(fn,wait){
    let timer = null
    function interval(){
        fn()
        timer = setTimeout(interval,wait)
    }
    interval()
    return {
        cancel: () => {
            clearTimeout(timer)
        }
    }
}

/**setInterval存在的问题
 * setInterval(fn,time) 这串代码的意思是：fn在每隔time毫秒之后被推入任务队列，注意：不是直接放入任务队列
 * 在setInterval被推入任务队列时，如果在它前面有很多任务或者某个任务等待时间较长，比如网络请求等，
 * 那么这个定时器的执行时间和我们预定它执行的时间可能并不一致
 * 意味着，如果我们定时器里面的代码需要进行大量的计算，花费的时间就会比较长，那么我上一次的代码还没有执行完毕，
 * 那么我又推入了下一次的代码去任务队列，这个时候就会变得不准确
 */

/**
 * setInterval缺点以及setTimeout
 * 1、setInterval缺点
 * 根据上文我们得知，setInterval是存在以下缺点的：
 * 1、使用setInterval时，某些间隔会被跳过（如果上一次执行代码没有执行，那么这次的执行代码将不会被放入队列，会被跳过）
 * 2、可能多个定时器会连续执行（上一次代码在队列中等待还没有开始执行，然后定时器又添加第二次代码，
 * 第一次代码等待时间和执行时间刚好等于第二次代码执行时间）
 * 通俗来说：每个setTimeout产生的任务会直接push到任务队列中；而setInterval在每次把任务push到任务队列前，
 * 都要进行以下判断（看上次的任务是否仍在队列中，如果有则不添加，没有则添加）
 */

/**
 * 再次强调，定时器指定的时间间隔，表示的是何时将定时器的代码添加到消息队列，
 * 而不是何时执行代码。所以真正何时执行代码的时间是不能保证的，取决于何时被主线程的事件循环取到，并执行。
 */

